//
// Created by Administrator on 2025/1/16.
//

#include "MxzxFileUtil.h"
#include "MxzxLog.h"
#define MAX_FILENAME_LENGTH 50

// 生成随机字符的函数
char randomChar() {
     const char charset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    const int index = rand() % (sizeof(charset) - 1); // 生成随机索引
    return charset[index]; // 返回随机字符
}

// 生成指定长度的随机字符串的函数
char* randomString(const int length) {
    char* str = (char*)(malloc((length + 1) * sizeof(char))); // 分配内存
    if (str == NULL) {
        LOGD( "内存分配失败\n");
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < length; i++) {
        str[i] = randomChar(); // 生成随机字符并赋值
    }
    str[length] = '\0'; // 添加字符串终止符

    return str;
}

// 生成当前时间字符串的函数
char* currentTimeString() {
    time_t now;
    time(&now);
    const struct tm *tm_info = localtime(&now);

    char* time_str = (char*)malloc(16 * sizeof(char)); // 分配内存
    if (time_str == NULL) {
        LOGD( "内存分配失败\n");
        exit(EXIT_FAILURE);
    }

    strftime(time_str, 16, "%Y%m%d%H%M%S", tm_info); // 格式化时间
    return time_str;
}
// 写入WAV文件头
void write_wav_header(FILE* wav_file, int sample_rate, int num_channels, int bits_per_sample, int pcm_data_size) {
    WAVHeader header = {
        .riff = {'R', 'I', 'F', 'F'},
        .wave = {'W', 'A', 'V', 'E'},
        .fmt = {'f', 'm', 't', ' '},
        .fmt_chunk_size = 16,
        .audio_format = 1,  // PCM
        .num_channels = num_channels,
        .sample_rate = sample_rate,
        .byte_rate = sample_rate * num_channels * (bits_per_sample / 8),
        .block_align = num_channels * (bits_per_sample / 8),
        .bits_per_sample = bits_per_sample,
        .data = {'d', 'a', 't', 'a'},
        .data_chunk_size = pcm_data_size,
    };

    header.chunk_size = 36 + pcm_data_size;  // RIFF chunk size

    fwrite(&header, sizeof(WAVHeader), 1, wav_file);
}
ComFlowResult *newWavFromPcmFile(const char *pcmFilePath,const char *wavFilePath,int sample_rate, int num_channels ,int bits_per_sample) {
    ComFlowResult *flow_result = (ComFlowResult *)malloc(sizeof(ComFlowResult));
    if (flow_result == NULL) {
        return NULL;
    }
    flow_result->code=0;
    flow_result->msg="";
    const char* pcm_file = pcmFilePath;
    const char* wav_file = wavFilePath;

    FILE* pcm = fopen(pcm_file, "rb");
    if (!pcm) {
        // perror("Failed to open PCM file");
        // return 1;
        flow_result->code=-1;
        flow_result->msg="打开PCM文件失败";
        return flow_result;
    }

    fseek(pcm, 0, SEEK_END);
    int pcm_data_size = ftell(pcm);
    fseek(pcm, 0, SEEK_SET);

    FILE* wav = fopen(wav_file, "wb");
    if (!wav) {
        flow_result->code=-1;
        flow_result->msg="打开WAV文件失败";
        return flow_result;
    }

    write_wav_header(wav, sample_rate, num_channels, bits_per_sample, pcm_data_size);

    // 将 PCM 数据写入 WAV 文件
    uint8_t buffer[1024];
    size_t bytes_read;
    while ((bytes_read = fread(buffer, 1, sizeof(buffer), pcm)) > 0) {
        fwrite(buffer, 1, bytes_read, wav);
    }
    flow_result->result=wavFilePath;

    fclose(pcm);
    fclose(wav);
    return flow_result;
}
char* mxzxNewRandomFileName(const char *suffix) {
    // 生成当前时间字符串
    char* time_str = currentTimeString();
    // 生成随机字符串
    char* random_str = randomString(8);

    // 拼接文件名
    char* filename = (char*)malloc(MAX_FILENAME_LENGTH * sizeof(char));  // 动态分配内存
    snprintf(filename, MAX_FILENAME_LENGTH, "%s_%s.%s", time_str, random_str, suffix);  // 使用 snprintf 避免缓冲区溢出
    // 释放内存
    free(time_str);
    free(random_str);
    return filename;
}
char* mxzxNewRandomFilePath(const char* fileDir, const char *suffix) {
    char* randomWavName = mxzxNewRandomFileName(suffix);
    char* wavOutFileAllPath =  (char*)malloc(MAX_FILENAME_LENGTH*3 * sizeof(char));
    snprintf(wavOutFileAllPath,MAX_FILENAME_LENGTH*3, "%s%s", fileDir, randomWavName);
    free(randomWavName);
    return wavOutFileAllPath;
}

int mxzxNewFileForName(const char* allFilePath){
    // 创建并打开文件
    FILE *file = fopen(allFilePath, "wb");
    if (file == NULL) {
        LOGD( "创建文件失败\n");
        return 0;
    }
    // 关闭文件
    fclose(file);
    return 1;
}

void format_time(double total_seconds, int *hours, int *minutes, int *seconds) {
    *hours = (int)(total_seconds / 3600);
    *minutes = (((int)total_seconds) % 3600 / 60);
    *seconds = ((int)total_seconds) % 60;
}

FILE *openFileByPath(const char* allFilePath){
    // 创建并打开文件
    // FILE* fp = NULL;
    // // 使用 fopen_s 替代（Windows 特有）
    // const errno_t err = fopen_s(&fp, "filename.txt", "r");
    // if (err != 0 || fp == NULL) {
    //     LOGD( "创建文件失败\n");
    //     return NULL;
    // }
    // return fp;
    FILE *file = fopen(allFilePath, "wb");
    if (file == NULL) {
        LOGD( "创建文件失败\n");
        return NULL;
    }
    return file;
}
void updateFileTime(const char *filename) {
    // 创建一个utimbuf结构体
    // struct utimbuf new_times;
    // new_times.actime = time(NULL);  // 当前时间作为访问时间
    // new_times.modtime = time(NULL); // 当前时间作为修改时间
    //
    // // 修改文件的访问时间和修改时间
    // if (utime(filename, &new_times) == -1) {
    //     perror("utime");
    //     return;
    // }

    LOGD("File times updated successfully\n");
}
int isMp3File(const char *filename) {
    FILE *file = fopen(filename, "rb");
    if (file == NULL) {
        return -1; // File not found
    }

    unsigned char buffer[BUFFER_SIZE];
    size_t bytes_read = fread(buffer, 1, BUFFER_SIZE, file);
    fclose(file);

    if (bytes_read < BUFFER_SIZE) {
        return -1; // File too small
    }

    // Check for WAV
    if (memcmp(buffer, "RIFF", 4) == 0 && memcmp(buffer + 8, "WAVE", 4) == 0) {
        return -1;
    }

    // Check for MP3
    if (memcmp(buffer, "ID3", 3) == 0 || memcmp(buffer, "\xFF\xFB", 2) == 0) {
        return 1;
    }

    // Check for FLAC
    if (memcmp(buffer, "fLaC", 4) == 0) {
        return -1;
    }

    // Check for OGG
    if (memcmp(buffer, "OggS", 4) == 0) {
        return -1;
    }

    return -1; // No match found
}
